/* eslint-disable no-array-constructor */
/* eslint-disable no-new-object */
/* eslint-disable eqeqeq */
/*
 * @Author: HYQ
 * @Date: 2021-05-28 10:38:41
 * @LastEditTime: 2021-12-01 14:10:03
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: src/components/calendar/components/dateFunc.js
 */
var shortMonth = [
  'Jan',
  'Feb',
  'Mar',
  'Apr',
  'May',
  'Jun',
  'Jul',
  'Aug',
  'Sep',
  'Oct',
  'Nov',
  'Dec'
]
var defMonthNames = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December'
]
var i18n = {
  xgcalendar: {
    dateformat: {
      fulldaykey: 'yyyyMMdd',
      fulldayshow: 'yyyy年M月d日',
      fulldayvalue: 'yyyy-M-d',
      Md: 'M/d (W)',
      Md3: 'M月d日',
      AM: '上午',
      PM: '下午',
      separator: '-',
      year_index: 0,
      month_index: 1,
      day_index: 2,
      day: 'd日',
      sun: '周日',
      mon: '周一',
      tue: '周二',
      wed: '周三',
      thu: '周四',
      fri: '周五',
      sat: '周六',
      jan: '一月',
      feb: '二月',
      mar: '三月',
      apr: '四月',
      may: '五月',
      jun: '六月',
      jul: '七月',
      aug: '八月',
      sep: '九月',
      oct: '十月',
      nov: '十一月',
      dec: '十二月'
    },
    no_implemented: '没有实现',
    to_date_view: '点击转到该日期的日视图',
    i_undefined: '未设置',
    allday_event: '全天日程',
    repeat_event: '跨天日程',
    time: '时  间',
    event: '事  件',
    location: '地  点',
    participant: '参与人',
    get_data_exception: '获取数据发生异常',
    new_event: '新日程',
    confirm_delete_event: '确定删除该日程吗？',
    confrim_delete_event_or_all: '删除此序列还是单个事件？\r\n点击[确定]删除事件,点击[取消]删除序列',
    data_format_error: '数据格式错误！',
    invalid_title: '日程标题不能为空且不能包含符号($<>)',
    view_no_ready: '视图未准备就绪',
    example: '例如：有个办公会议',
    content: '内 容',
    create_event: '创建日程',
    update_detail: '修改日程详细信息',
    click_to_detail: '点击查看详细',
    i_delete: '删除',
    day_plural: '天',
    others: '另外',
    item: '个'
  }
}

const dateFunc = {
  __WDAY () {
    return new Array(i18n.xgcalendar.dateformat.sun, i18n.xgcalendar.dateformat.mon, i18n.xgcalendar.dateformat.tue, i18n.xgcalendar.dateformat.wed, i18n.xgcalendar.dateformat.thu, i18n.xgcalendar.dateformat.fri, i18n.xgcalendar.dateformat.sat)
  },
  __MonthName () {
    return new Array(i18n.xgcalendar.dateformat.jan, i18n.xgcalendar.dateformat.feb, i18n.xgcalendar.dateformat.mar, i18n.xgcalendar.dateformat.apr, i18n.xgcalendar.dateformat.may, i18n.xgcalendar.dateformat.jun, i18n.xgcalendar.dateformat.jul, i18n.xgcalendar.dateformat.aug, i18n.xgcalendar.dateformat.sep, i18n.xgcalendar.dateformat.oct, i18n.xgcalendar.dateformat.nov, i18n.xgcalendar.dateformat.dec)
  },
  getDuration (date) {
    // how many days of this month
    const dt = new Date(date)
    // var month = dt.getMonth()
    dt.setMonth(dt.getMonth() + 1)
    dt.setDate(0)
    return dt.getDate()
  },
  changeDay (date, num) {
    const dt = new Date(date)
    return new Date(dt.setDate(dt.getDate() + num))
  },
  getStartDate (date) {
    // return first day of this month
    return new Date(date.getFullYear(), date.getMonth(), 1)
  },
  getEndDate (date) {
    // get last day of this month
    const dt = new Date(date.getFullYear(), date.getMonth() + 1, 1) // 1st day of next month
    return new Date(dt.setDate(dt.getDate() - 1)) // last day of this month
  },
  format (date, format, monthNames) {
    monthNames = monthNames || defMonthNames
    if (typeof date === 'string') {
      date = new Date(date.replace(/-/g, '/'))
    } else {
      date = new Date(date)
    }

    var map = {
      M: date.getMonth() + 1,
      d: date.getDate(),
      h: date.getHours(),
      m: date.getMinutes(),
      s: date.getSeconds(),
      q: Math.floor((date.getMonth() + 3) / 3),
      S: date.getMilliseconds()
    }

    format = format.replace(/([yMdhmsqS])+/g, (all, t) => {
      var v = map[t]
      if (v !== undefined) {
        if (all === 'MMMM') {
          return monthNames[v - 1]
        }
        if (all === 'MMM') {
          return shortMonth[v - 1]
        }
        if (all.length > 1) {
          v = '0' + v
          v = v.substr(v.length - 2)
        }
        return v
      } else if (t === 'y') {
        return String(date.getFullYear()).substr(4 - all.length)
      }
      return all
    })
    return format
  },
  /**
   *
   * @param {*} events 数据源
   * @param {*} startday  以周几开头 0-6
   * @param {*} daylength 一周天数 7
   * @param {*} rbdate 视图上的第一天
   * @param {*} redate 视图上的最后天
   */
  formatEventsInHashTable (events, startday, daylength, rbdate, redate) {
    console.log('redate: ', redate)
    console.log('rbdate: ', rbdate)
    console.log('events: ', events)
    // eslint-disable-next-line no-new-object
    var hast = new Object()
    var l = events.length
    for (var i = 0; i < l; i++) {
      var sD = new Date(events[i].start)// 事件中的开始时间
      var eD = new Date(events[i].end) // 事件中的结束时间
      var diff = this.DateDiff.call(dateFunc, 'd', sD, eD)
      var s = {}
      s.event = events[i]
      s.day = sD.getDate()
      s.year = sD.getFullYear()
      s.month = sD.getMonth() + 1
      s.allday = true
      s.crossday = true
      s.reevent = true // 循环日程
      s.daystr = s.year + '/' + s.month + '/' + s.day
      s.st = {}
      s.st.hour = sD.getHours()
      s.st.minute = sD.getMinutes()
      s.st.p = s.st.hour * 60 + s.st.minute // 时间的开始位置
      s.et = {}
      s.et.hour = eD.getHours()
      s.et.minute = eD.getMinutes()
      s.et.p = s.et.hour * 60 + s.et.minute // 时间的开始位置

      if (diff > 0) {
        if (sD < rbdate) { // 开始时间超出范围
          sD = rbdate
        }
        if (eD > redate) { // 结束时间超出范围
          eD = redate
        }
        var f = startday - sD.getDay()
        if (f > 0) { f -= daylength }
        var sdtemp = this.DateAdd.call(dateFunc, 'd', f, sD)
        do {
          var d = this.Clone.call(dateFunc, s)
          var key = this.dateFormat.call(dateFunc, sD, i18n.xgcalendar.dateformat.fulldaykey)
          var x = this.DateDiff.call(dateFunc, 'd', sdtemp, eD)
          if (hast[key] == null) {
            hast[key] = []
          }
          // 处理表格跨界，分为跨周和不跨周
          d.colSpan = (x >= daylength) ? daylength - this.DateDiff.call(dateFunc, 'd', sdtemp, sD) : this.DateDiff.call(dateFunc, 'd', sD, eD) + 1
          hast[key].push(d)
          d = null
          sD = sdtemp = this.DateAdd.call(dateFunc, 'd', daylength, sdtemp)
        } while (sdtemp <= eD)
        // for (; sdtemp <= eD; sD = sdtemp = this.DateAdd.call(dateFunc, 'd', daylength, sdtemp)) {
        //   var d = this.Clone.call(dateFunc, s)
        //   var key = this.dateFormat.call(dateFunc, sD, i18n.xgcalendar.dateformat.fulldaykey)
        //   var x = this.DateDiff.call(dateFunc, 'd', sdtemp, eD)
        //   if (hast[key] == null) {
        //     hast[key] = []
        //   }
        //   // 处理表格跨界，分为跨周和不跨周
        //   d.colSpan = (x >= daylength) ? daylength - this.DateDiff.call(dateFunc, 'd', sdtemp, sD) : this.DateDiff.call(dateFunc, 'd', sD, eD) + 1
        //   hast[key].push(d)
        //   d = null
        // }
      } else {
        var key1 = this.dateFormat.call(dateFunc, events[i].start, i18n.xgcalendar.dateformat.fulldaykey)
        if (hast[key1] == null) {
          hast[key1] = []
        }
        s.colSpan = 1
        hast[key1].push(s)
      }
      s = null
    }
    return hast
  },
  Clone (obj) {
    var objClone = new Object()
    if (obj.constructor == Object) {
      objClone = new obj.constructor()
    } else {
      objClone = new obj.constructor(obj.valueOf())
    }
    for (var key in obj) {
      if (objClone[key] != obj[key]) {
        if (typeof (obj[key]) == 'object') {
          objClone[key] = this.Clone.call(dateFunc, obj[key])
        } else {
          objClone[key] = obj[key]
        }
      }
    }
    objClone.toString = obj.toString
    objClone.valueOf = obj.valueOf
    return objClone
  },
  DateAdd (interval, number, idate) {
    number = parseInt(number)
    var date
    if (typeof (idate) == 'string') {
      const splitDate = idate.split(/\D/)
      date = new Date(splitDate.join(','))
    }

    if (typeof (idate) == 'object') {
      date = new Date(idate.toString())
    }
    switch (interval) {
      case 'y': date.setFullYear(date.getFullYear() + number); break
      case 'm': ; break
      case 'd': date.setDate(date.getDate() + number); break
      case 'w': date.setDate(date.getDate() + 7 * number); break
      case 'h': date.setHours(date.getHours() + number); break
      case 'n': date.setMinutes(date.getMinutes() + number); break
      case 's': date.setSeconds(date.getSeconds() + number); break
      case 'l': date.setMilliseconds(date.getMilliseconds() + number); break
    }
    return date
  },
  DateDiff (interval, d1, d2) {
    d1 = new Date(d1)
    d2 = new Date(d2)
    switch (interval) {
      case 'd': // 天
      case 'w':
        d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate())
        d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate())
        break // w
      case 'h':
        d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate(), d1.getHours())
        d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate(), d2.getHours())
        break // h
      case 'n':
        d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate(), d1.getHours(), d1.getMinutes())
        d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate(), d2.getHours(), d2.getMinutes())
        break
      case 's':
        d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate(), d1.getHours(), d1.getMinutes(), d1.getSeconds())
        d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate(), d2.getHours(), d2.getMinutes(), d2.getSeconds())
        break
    }
    var t1 = d1.getTime(); var t2 = d2.getTime()
    var diff = NaN
    switch (interval) {
      case 'y': diff = d2.getFullYear() - d1.getFullYear(); break // y
      case 'm': diff = (d2.getFullYear() - d1.getFullYear()) * 12 + d2.getMonth() - d1.getMonth(); break // m
      case 'd': diff = Math.floor(t2 / 86400000) - Math.floor(t1 / 86400000); break
      case 'w': diff = Math.floor((t2 + 345600000) / (604800000)) - Math.floor((t1 + 345600000) / (604800000)); break // w
      case 'h': diff = Math.floor(t2 / 3600000) - Math.floor(t1 / 3600000); break // h
      case 'n': diff = Math.floor(t2 / 60000) - Math.floor(t1 / 60000); break //
      case 's': diff = Math.floor(t2 / 1000) - Math.floor(t1 / 1000); break // s
      case 'l': diff = t2 - t1; break
    }
    return diff
  },
  dateFormat (time, format) {
    time = new Date(time)
    var o = {
      'M+': time.getMonth() + 1,
      'd+': time.getDate(),
      'h+': time.getHours() > 12 ? time.getHours() - 12 : time.getHours(),
      'H+': time.getHours(),
      'm+': time.getMinutes(),
      's+': time.getSeconds(),
      'q+': Math.floor((time.getMonth() + 3) / 3),
      w: '0123456'.indexOf(time.getDay()),
      t: time.getHours() < 12 ? i18n.xgcalendar.dateformat.AM : i18n.xgcalendar.dateformat.PM,
      W: this.__WDAY.call(dateFunc)[time.getDay()],
      L: this.__MonthName.call(dateFunc)[time.getMonth()] // non-standard
    }
    if (/(y+)/.test(format)) {
      format = format.replace(RegExp.$1, (time.getFullYear() + '').substr(4 - RegExp.$1.length))
    }
    for (var k in o) {
      if (new RegExp('(' + k + ')').test(format)) { format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)) }
    }
    return format
  }
}

module.exports = dateFunc
